package personal.jinhui.paprika.ui;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.io.InputStream;
import java.io.IOException;

import org.jivesoftware.smack.util.StringUtils;

import personal.jinhui.paprika.providers.AvatarProvider;
import personal.jinhui.paprika.service.Message;
import personal.jinhui.paprika.service.PaprikaChat;
import personal.jinhui.paprika.service.Contact;

import personal.jinhui.paprika.utils.SortedList;

import android.app.Activity;
import android.content.ComponentName;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.SharedPreferences;
import android.net.Uri;
import android.os.Bundle;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;

import android.view.ViewGroup;
import android.view.WindowManager;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.ListView;
import android.widget.TextView;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.LayerDrawable;

import personal.jinhui.paprika.R;
import personal.jinhui.paprika.service.aidl.IChat;
import personal.jinhui.paprika.service.aidl.IChatManager;
import personal.jinhui.paprika.service.aidl.IChatListener;
import personal.jinhui.paprika.service.aidl.IMessageListener;
import personal.jinhui.paprika.service.aidl.IXmppFacade;

/**
 * The contact list activity displays the roster of the user.
 */
public class SessionListActivity extends Activity {
	private static final String TAG = "SessionListActivity";

	private static final Intent SERVICE_INTENT = new Intent();
	static {
		SERVICE_INTENT.setComponent(new ComponentName(
				"personal.jinhui.paprika",
				"personal.jinhui.paprika.PaprikaService"));
	}

	private final PaprikaSessionListAdapter mAdapterSessionList = new PaprikaSessionListAdapter();
	private final PaprikaSessionListOnClick mOnSessionClick = new PaprikaSessionListOnClick();
	private final Handler mHandler = new Handler();
	private final ServiceConnection mServConn = new PaprikaServiceConnection();
	private final ComparatorChatListByTimestamp<IChat> mComparator = new ComparatorChatListByTimestamp<IChat>();
	private List<IChat> mListChat;
	private IXmppFacade mXmppFacade;
	private IChatManager mChatManager;

	private final ChatListener mChatListener = new ChatListener();
	
	private SharedPreferences mSettings;
	private LayoutInflater mInflater;
	private boolean mBinded;

	/**
	 * Constructor.
	 */
	public SessionListActivity() {
	}

	@Override
	protected void onCreate(Bundle saveBundle) {
		super.onCreate(saveBundle);
		setContentView(R.layout.sessionlist);
		mSettings = PreferenceManager.getDefaultSharedPreferences(this);

		getWindow().setSoftInputMode(
				WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN);

		mInflater = getLayoutInflater();
		mListChat = new ArrayList<IChat>();
		ListView listView = (ListView) findViewById(R.id.sessionlist);
		listView.setOnItemClickListener(mOnSessionClick);
		registerForContextMenu(listView);
		listView.setAdapter(mAdapterSessionList);
	}

	@Override
	protected void onStart() {
		// TODO Auto-generated method stub
		super.onStart();

		Log.d("#####", "SessionList onStart!!!");

		if (!mBinded) {
			mBinded = getApplicationContext().bindService(SERVICE_INTENT,
					mServConn, BIND_AUTO_CREATE);
		}
	}

	@Override
	protected void onResume() {
		// TODO Auto-generated method stub
		super.onResume();
		Log.d("#####", "SessionList onResume!!!");
	}

	/**
	 * {@inheritDoc}
	 */
	@Override
	protected void onPause() {
		super.onPause();

		if (mBinded) {
			getApplicationContext().unbindService(mServConn);
			mBinded = false;
		}
		mXmppFacade = null;
	}

	@Override
	protected void onDestroy() {
		super.onDestroy();
	}

	private void buildSessionList() {

		Log.d(TAG, "buildSessionList");

		mListChat.clear();



		Collections.sort(mListChat, mComparator);



		Log.d("#########", "mListChat.size(), " + mListChat.size());

		mAdapterSessionList.notifyDataSetChanged();
	}

	/**
	 * Adapter contact list.
	 */
	private class PaprikaSessionListAdapter extends BaseAdapter {

		/**
		 * {@inheritDoc}
		 */
		@Override
		public int getCount() {
			return mListChat.size();
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public Object getItem(int position) {
			return mListChat.get(position);
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public long getItemId(int position) {
			return mListChat.get(position).hashCode();
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public View getView(int position, View convertView, ViewGroup parent) {
			View v = convertView;
			if (convertView == null) {
				v = mInflater.inflate(R.layout.sessionlist_session, null);
			}
			IChat c = mListChat.get(position);
			bindView(v, c);
			return v;
		}

		/**
		 * Adapte curContact to the view.
		 * 
		 * @param view
		 *            the row view.
		 * @param curContact
		 *            the current contact.
		 */
		private void bindView(View view, IChat curChat) {
			if (curChat != null) {

				try {
					TextView v = (TextView) view
							.findViewById(R.id.contact_name);
					v.setText(curChat.getParticipant().getJID());

					int size = curChat.getMessages().size();
					Message message = curChat
							.getMessages().get(size - 1);
					TextView v1 = (TextView) view.findViewById(R.id.timestap);
					v1.setText(message.getTimestamp().toString());
					TextView v2 = (TextView) view
							.findViewById(R.id.last_message);
					v2.setText(message.getBody());

					ImageView img = (ImageView) view
							.findViewById(R.id.contact_avatar);
					Drawable draw = getAvatarStatusDrawable(curChat
							.getParticipant().getAvatarId());
					img.setImageDrawable(draw);
					img.setImageLevel(curChat.getParticipant().getStatus());

				} catch (RemoteException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}
		}

		/**
		 * Get a LayerDrawable containing the avatar and the status icon. The
		 * status icon will change with the level of the drawable.
		 * 
		 * @param avatarId
		 *            the avatar id to retrieve or null to get default
		 * @return a LayerDrawable
		 */
		private Drawable getAvatarStatusDrawable(String avatarId) {
			Drawable avatarDrawable = null;
			if (avatarId != null) {
				Uri uri = AvatarProvider.CONTENT_URI.buildUpon()
						.appendPath(avatarId).build();
				InputStream in = null;
				try {
					try {
						in = getContentResolver().openInputStream(uri);
						avatarDrawable = Drawable
								.createFromStream(in, avatarId);
					} finally {
						if (in != null)
							in.close();
					}
				} catch (IOException e) {
					Log.w(TAG, "Error while setting the avatar " + avatarId, e);
				}
			}
			if (avatarDrawable == null)
				avatarDrawable = getResources().getDrawable(
						R.drawable.default_man);
			LayerDrawable ld = (LayerDrawable) getResources().getDrawable(
					R.drawable.avatar_status);
			ld.setLayerInset(1, 16, 16, 0, 0);
			ld.setDrawableByLayerId(R.id.avatar, avatarDrawable);
			return ld;
		}

	}

	/**
	 * The service connection used to connect to the Paprika service.
	 */
	private class PaprikaServiceConnection implements ServiceConnection {

		/**
		 * Constructor.
		 */
		public PaprikaServiceConnection() {
		}

		@Override
		public void onServiceConnected(ComponentName name, IBinder service) {

			mXmppFacade = IXmppFacade.Stub.asInterface(service);
			try {
				mChatManager = mXmppFacade.getChatManager();
				mChatManager.addChatListener(mChatListener);

				// buildSessionList();
			} catch (RemoteException e) {
				e.printStackTrace();
			}
		}

		@Override
		public void onServiceDisconnected(ComponentName name) {

			mXmppFacade = null;
			mChatManager = null;
			/*
			 * try {
			 * mChatManager.removeChatCreationListener(mChatManagerListener); }
			 * catch (RemoteException e) { // TODO Auto-generated catch block
			 * e.printStackTrace(); }
			 */
			mListChat.clear();
			mBinded = false;
		}
	}

	/**
	 * Comparator Contact by status and name.
	 */
	private class ComparatorChatListByTimestamp<T> implements Comparator<T> {
		/**
		 * Constructor.
		 */
		public ComparatorChatListByTimestamp() {
		}

		@Override
		public int compare(T c1, T c2) {
			try {
				IChat chat1 = ((IChat) c1);
				IChat chat2 = ((IChat) c2);
				Message m1 = chat1
						.getMessages().get(chat1.getMessages().size() - 1);
				Message m2 = chat2
						.getMessages().get(chat2.getMessages().size() - 1);

				return m1.getTimestamp().compareTo(m2.getTimestamp());

			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			return 0;
		}
	}

	private class ChatListener extends IChatListener.Stub {

		/**
		 * Constructor.
		 */
		public ChatListener() {
		}

		@Override
		public void onChatCreated(IChat iChat, boolean locally) {
		}

		@Override
		public void onProcessMessage(IChat iChat, Message message)
				throws RemoteException {
			// TODO Auto-generated method stub
			
		}
	}
	
	/**
	 * Event simple click on item of the contact list.
	 */
	private class PaprikaSessionListOnClick implements OnItemClickListener {
		/**
		 * Constructor.
		 */
		public PaprikaSessionListOnClick() {
		}

		/**
		 * {@inheritDoc}
		 */
		@Override
		public void onItemClick(AdapterView<?> arg0, View v, int pos, long lpos) {
			try {
				IChat iChat = mListChat.get(pos);
				Intent i = new Intent(SessionListActivity.this,
						ChatActivity.class);
				i.setData(iChat.getParticipant().toUri());
				startActivity(i);
			} catch (RemoteException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
	}

}
